home *** CD-ROM | disk | FTP | other *** search
- #include <conio.h>
- #include <alloc.h>
- #include <mem.h>
- #include <string.h>
- #include <assert.h>
- #include "window.h"
- #include "_window.h"
-
- windowtype *windowchain = NULL;
- static unsigned int xpos, ypos;
-
- enum {TopLine, BottomLine, TopLeft, TopRight, BotLeft, BotRight,
- RightLine, LeftLine } _box;
-
- static unsigned char style[][8] =
- { { '-', '-', '+' , '+' , '+' , '+' , '|', '|' },
- { '\xC4', '\xC4', '\xDA', '\xBF', '\xC0', '\xD9', '\xB3', '\xB3' },
- { '\xCD', '\xCD', '\xC9', '\xBB', '\xC8', '\xBC', '\xBA', '\xBA' },
- { '\xC4', '\xCD', '\xDA', '\xB7', '\xD4', '\xBC', '\xB3', '\xBA' }
- };
-
-
- extern enum windowerrtype windowerr = WE_OK;
-
- /* box() --------------------------------------------------------
- * Routine to draw a box around a window.
- * --------------------------------------------------------------
- */
- static void box( unsigned char left,
- unsigned char top,
- unsigned char right,
- unsigned char bottom,
- char pattr,
- unsigned char *boxchars)
- {
- unsigned int tmp1, tmp2, attr = pattr << 8;
- int width, size, i;
- unsigned int *box;
-
- if ( (box = malloc( (size = (right-left+1)*(bottom-top+1))*2 )) == NULL )
- return;
-
- box[0] = ' ' | attr;
-
- /* Ripple move the space with current attribute to the entire block */
- /* This routine depends on memcpy not copying overlapping blocks
- * correctly in the forward direction and two bytes at a time.
- */
- memcpy(&box[1],box,size<<1);
-
- /* Top line */
- box[0] = boxchars[TopLeft] | attr;
- box[ ((width = right - left + 1) - 1) ] = boxchars[TopRight] |
- attr;
-
- box[1] = boxchars[TopLine] | attr;
-
- /* Ripple move - see above */
- memcpy(&box[2],&box[1],(width-3)<<1);
-
- tmp1 = boxchars[LeftLine] | attr;
- tmp2 = boxchars[RightLine] | attr;
- for (i = width; i<size-width; i += width)
- {
- box[i+width-1] = tmp1;
- box[i] = tmp2;
- }
-
- box[i] = boxchars[BotLeft] | attr;
- box[i+width-1] = boxchars[BotRight] | attr;
-
- box[i+1] = boxchars[BottomLine] | attr;
-
- /* Ripple move - see above */
- memcpy(&box[i+2],&box[i+1],(width-3)<<1);
- puttext(left,top,right,bottom,box);
-
- free(box);
-
- }
-
- /* makewindow() ---------------------------------------------------
- * Open a window on the screen. It becomes the current window.
- * RETURNS: 0 Success, 1 Out of memory, 2 Bad coordinates.
- * Coordinates must range from 2-79,2-24 (allow for the border).
- * Styles: 0 use not graphics chars, 1 single line, 2 double line
- * ----------------------------------------------------------------
- */
- windowtype *makewindow( unsigned char left,
- unsigned char top,
- unsigned char right,
- unsigned char bottom,
- char attr,
- unsigned char the_style,
- char *title)
- {
- windowtype *current;
- int size, len;
-
- windowerr = WE_OK;
-
- invalidate_backimage();
-
- /* Check the coordinates */
- if (top < 2 || bottom > 24 || left < 2 || right > 79 || top > bottom
- || left > right)
- {
- windowerr = WE_BADC;
- return NULL;
- }
-
- /* Allocate the memory for the window */
- if ( (current = malloc(sizeof(windowtype))) == NULL )
- {
- windowerr = WE_OMEM;
- return NULL;
- }
-
- /* Store the coorinates (including the border) */
- current->top = --top;
- current->bottom = ++bottom;
- current->left = --left;
- current->right = ++right;
-
- /* Calculate the size of the back-buffer */
- current->size = size = ((bottom-top+1)*(right-left+1)) << 1;
-
- /* Allocate the memory for the back buffer */
- if ( (current->backbuffer = malloc(size)) == NULL )
- {
- windowerr = WE_OMEM;
- return NULL;
- }
-
- /* Store the cursor position for the current window */
- if (windowchain)
- {
- windowchain->xpos = wherex();
- windowchain->ypos = wherey();
- }
- else
- {
- xpos = wherex();
- ypos = wherey();
- }
-
- /* Store the screen image that we are going to write over */
- gettext(left,top,right,bottom,current->backbuffer);
-
- /* Draw the border */
- window(1,1,80,25);
-
- box(left,top,right,bottom,attr,style[the_style]);
-
- /* Set the writting attribute */
- textattr(attr);
- current->attr = attr;
-
- /* Center the title on the border */
- /* If the title is too big for the border or it
- * is empty, don't write it
- */
- if ( (len = strlen(title)) <= (right - left) || len == 0 )
- {
- gotoxy( (right + left - len + 1) >> 1, top);
- cputs(title);
- }
-
- /* Section of the screen for the window */
- window(left+1,top+1,right-1,bottom-1);
-
-
- /* Register the window in the window chain, it becomes current */
- if (windowchain != NULL)
- windowchain->previous = current;
- current->next = windowchain;
- current->previous = NULL;
- windowchain = current;
-
- /* Return the window */
- return current;
- }
-
- /* deletewindow() ----------------------------------------------
- * Delete a window.
- * RETURN: 0 Success, -1 Failure.
- * -------------------------------------------------------------
- */
- int deletewindow(windowtype *current)
- {
- if (windowchain != current)
- return -1;
-
- invalidate_backimage();
-
- puttext(current->left,current->top,current->right,current->bottom,
- current->backbuffer);
-
- windowchain = current->next;
- free(current->backbuffer);
- free(current);
- if (windowchain != NULL)
- windowchain->previous = NULL;
-
- if (windowchain)
- {
- window(windowchain->left+1,windowchain->top+1,windowchain->right-1,
- windowchain->bottom-1);
- gotoxy(windowchain->xpos, windowchain->ypos);
- }
- else
- {
- window(1,1,80,25);
- gotoxy(xpos,ypos);
- }
- return 0;
- }
-